#include "vl53l0x_i2c.h"
#include "main.h"
#include "i2c.h"

/**
  * @brief  IIC写一个字节数据
  * @param  SlaveAddress：从机地址
  * @param  REG：寄存器地址
  * @param  REG_data：写数据
  * @retval 应答状态信息
  */
uint8_t VL_IIC_Write_1Byte(uint8_t SlaveAddress, 
                           uint8_t REG_Address,
                           uint8_t REG_data)
{
  static uint8_t _data[2];
  _data[0] = REG_Address;
  _data[1] = REG_data;
  HAL_I2C_Master_Transmit(&hi2c1, SlaveAddress, _data, 2, 100);
  return 0;
}

/**
  * @brief  IIC读一个字节数据
  * @param  SlaveAddress：从机地址
  * @param  REG：寄存器地址
  * @param  REG_data：写数据
  * @retval 应答状态信息
  */
uint8_t VL_IIC_Read_1Byte(uint8_t SlaveAddress, 
                          uint8_t REG_Address,
                          uint8_t *REG_data)
{
  static uint8_t _reg_addr;
  _reg_addr = REG_Address;
  HAL_I2C_Master_Transmit(&hi2c1, SlaveAddress, &_reg_addr, 1, 100);
  HAL_I2C_Master_Receive(&hi2c1, (SlaveAddress|0x01), REG_data, 1, 100);
  return 0;
}

/**
  * @brief  IIC写n字节数据
  * @param  SlaveAddress：从机地址
  * @param  REG：寄存器地址
  * @param  len：数据长度
  * @param  *buf：数据指针
  * @retval 应答状态信息
  */
uint8_t VL_IIC_Write_nByte(uint8_t SlaveAddress,
                           uint8_t REG_Address,
                           uint16_t len,
                           uint8_t *buf)
{
  static uint8_t _data[65];
  if(len > 64)
  {
    return 0xFF;
  }
  memset(_data, 0U, 65);
  _data[0] = REG_Address;
  memcpy(_data+1, buf, len);
  HAL_I2C_Master_Transmit(&hi2c1, SlaveAddress, _data, len+1, 100);
  return 0;
}

/**
  * @brief  IIC读n字节数据
  * @param  SlaveAddress：从机地址
  * @param  REG：寄存器地址
  * @param  len：数据长度
  * @param  *buf：数据指针
  * @retval 应答状态信息
  */
uint8_t VL_IIC_Read_nByte(uint8_t SlaveAddress,
                          uint8_t REG_Address,
                          uint16_t len,
                          uint8_t *buf)
{
  static uint8_t _reg_addr;
  _reg_addr = REG_Address;
  HAL_I2C_Master_Transmit(&hi2c1, SlaveAddress, &_reg_addr, 1, 100);
  HAL_I2C_Master_Receive(&hi2c1, (SlaveAddress|0x01), buf, len, 100);
  return 0;
}


/**
  * @brief  VL53L0X 写多个数据
  * @param  address:地址
  * @param  index:偏移地址
  * @param  pdata:数据指针
  * @param  count:长度 最大65535
  * @retval 应答状态信息
  */
uint8_t VL53L0X_write_multi(uint8_t address,
                            uint8_t index,
                            uint8_t *pdata,
                            uint16_t count)
{
    uint8_t status = STATUS_OK;

    if(VL_IIC_Write_nByte(address,index,count,pdata))
    {
       status  = STATUS_FAIL;
    }

    return status;
}


/**
  * @brief  VL53L0X 读多个数据
  * @param  address:地址
  * @param  index:偏移地址
  * @param  pdata:数据指针
  * @param  count:长度 最大65535
  * @retval 应答状态信息
  */
uint8_t VL53L0X_read_multi(uint8_t address,
                           uint8_t index,
                           uint8_t *pdata,
                           uint16_t count)
{
    uint8_t status = STATUS_OK;

    if(VL_IIC_Read_nByte(address,index,count,pdata))
    {
      status  = STATUS_FAIL;
    }

    return status;
}

/**
  * @brief  写1个数据(单字节)
  * @param  address:地址
  * @param  index:偏移地址
  * @param  data:数据(8位)
  * @retval 应答状态信息
  */
uint8_t VL53L0X_write_byte(uint8_t address,uint8_t index,uint8_t data)
{
    uint8_t status = STATUS_OK;

    status = VL53L0X_write_multi(address,index,&data,1);

    return status;
}

/**
  * @brief  写1个数据(双字节)
  * @param  address:地址
  * @param  index:偏移地址
  * @param  data:数据(8位)
  * @retval 应答状态信息
  */
uint8_t VL53L0X_write_word(uint8_t address,uint8_t index,uint16_t data)
{
    uint8_t status = STATUS_OK;
    
    uint8_t buffer[2];
    
    //将16位数据拆分成8位
    buffer[0] = (uint8_t)(data>>8);//高八位
    buffer[1] = (uint8_t)(data&0xff);//低八位
    
    if(index%2==1)
    {  
        //串行通信不能处理对非2字节对齐寄存器的字节
        status = VL53L0X_write_multi(address,index,&buffer[0],1);
        status = VL53L0X_write_multi(address,index,&buffer[0],1);
    }else
    {
        status = VL53L0X_write_multi(address,index,buffer,2);
    }
    
    return status;
}

/**
  * @brief  写数据(4个字节)
  * @param  address:地址
  * @param  index:偏移地址
  * @param  data:数据(8位)
  * @retval 应答状态信息
  */
uint8_t VL53L0X_write_dword(uint8_t address,
                            uint8_t index,
                            uint32_t data)
{
    
    uint8_t status = STATUS_OK;

    uint8_t buffer[4];  
    
    //将32位数据拆分成8位
    buffer[0] = (uint8_t)(data>>24);
    buffer[1] = (uint8_t)((data&0xff0000)>>16);
    buffer[2] = (uint8_t)((data&0xff00)>>8);
    buffer[3] = (uint8_t)(data&0xff);
    
    status = VL53L0X_write_multi(address,index,buffer,4);
    
    return status;
}


/**
  * @brief  读数据(1个字节)
  * @param  address:地址
  * @param  index:偏移地址
  * @param  data:数据(8位)
  * @retval 应答状态信息
  */
uint8_t VL53L0X_read_byte(uint8_t address,
                          uint8_t index,
                          uint8_t *pdata)
{
    uint8_t status = STATUS_OK;
     
    status = VL53L0X_read_multi(address,index,pdata,1);
    
    return status;
     
}

/**
  * @brief  读数据(2个字节)
  * @param  address:地址
  * @param  index:偏移地址
  * @param  data:数据(8位)
  * @retval 应答状态信息
  */
uint8_t VL53L0X_read_word(uint8_t address,
                          uint8_t index,
                          uint16_t *pdata)
{
    uint8_t status = STATUS_OK;
    
		uint8_t buffer[2];
    
    status = VL53L0X_read_multi(address,index,buffer,2);
    
    *pdata = ((uint16_t)buffer[0]<<8)+(uint16_t)buffer[1];
    
    return status;
    
}

/**
  * @brief  读数据(4个字节)
  * @param  address:地址
  * @param  index:偏移地址
  * @param  data:数据(8位)
  * @retval 应答状态信息
  */
uint8_t VL53L0X_read_dword(uint8_t address,
                           uint8_t index,
                           uint32_t *pdata)
{
    uint8_t status = STATUS_OK;
    
    uint8_t buffer[4];
    
    status = VL53L0X_read_multi(address,index,buffer,4);
    
    *pdata = ((uint32_t)buffer[0]<<24)+((uint32_t)buffer[1]<<16)+
            ((uint32_t)buffer[2]<<8)+((uint32_t)buffer[3]);
    
    return status;
    
}
